/*
 * $Id: ServletDispatcherResult.java 658883 2008-05-21 21:31:04Z musachy $
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.fractalist.base.core.web.result;

import java.util.Map;

import javax.servlet.RequestDispatcher;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.PageContext;

import org.apache.struts2.ServletActionContext;
import org.apache.struts2.views.util.UrlHelper;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.Result;

/**
 * 从struts2的源码中拿来用，从actionContext的result中接收要渲染的jsp文件
 * 
 * @author radio
 * 
 */
public class DispatcherResult implements Result {

	private static final long serialVersionUID = -1970659272360685627L;

	/**
	 * The result parameter name to set the name of the action to chain to.
	 */
	public static final String DEFAULT_PARAM = "actionName";

	public static String getDefaultParam() {
		return DEFAULT_PARAM;
	}

	/**
	 * Dispatches to the given location. Does its forward via a
	 * RequestDispatcher. If the dispatch fails a 404 error will be sent back in
	 * the http response.
	 * 
	 * @param finalLocation
	 *            the location to dispatch to.
	 * @param invocation
	 *            the execution state of the action
	 * @throws Exception
	 *             if an error occurs. If the dispatch fails the error will go
	 *             back via the HTTP request.
	 */
	@SuppressWarnings("unchecked")
	public void execute(ActionInvocation invocation) throws Exception {
		PageContext pageContext = ServletActionContext.getPageContext();
		String finalLocation = (String) ActionContext.getContext().get(
				"location");
		if (pageContext != null) {
			pageContext.include(finalLocation);
		} else {
			HttpServletRequest request = ServletActionContext.getRequest();
			HttpServletResponse response = ServletActionContext.getResponse();
			RequestDispatcher dispatcher = request
					.getRequestDispatcher(finalLocation);

			// add parameters passed on the location to #parameters
			// see WW-2120
			if (invocation != null && finalLocation != null
					&& finalLocation.length() > 0
					&& finalLocation.indexOf("?") > 0) {
				String queryString = finalLocation.substring(finalLocation
						.indexOf("?") + 1);
				Map<?, ?> parameters = (Map<?, ?>) invocation
						.getInvocationContext().getContextMap()
						.get("parameters");
				Map queryParams = null;// UrlHelper.parseQueryString(queryString,
										// true);
				if (queryParams != null && !queryParams.isEmpty())
					parameters.putAll(queryParams);
			}

			// if the view doesn't exist, let's do a 404
			if (dispatcher == null) {
				response.sendError(404, "result '" + finalLocation
						+ "' not found");

				return;
			}

			if (!response.isCommitted()
					&& (request
							.getAttribute("javax.servlet.include.servlet_path") == null)) {
				request.setAttribute("struts.view_uri", finalLocation);
				request.setAttribute("struts.request_uri",
						request.getRequestURI());

				dispatcher.forward(request, response);
			} else {
				dispatcher.include(request, response);
			}
		}
	}

}
